package com.bestcem.xm.award.controller;

import cn.hutool.core.lang.Validator;
import com.alibaba.fastjson.JSON;
import com.bestcem.xm.award.config.SignConfig;
import com.bestcem.xm.award.controller.param.requestaward.GetRequestAwardQuery;
import com.bestcem.xm.award.grpc.service.param.requestaward.GetRequestAwardParam;
import com.bestcem.xm.award.service.impl.AwardDispatcher;
import com.bestcem.xm.common.core.constant.ReqErrorCodeConstants;
import com.bestcem.xm.common.core.domain.web.ServiceResult;
import com.bestcem.xm.common.core.domain.web.XmResultJson;
import com.bestcem.xm.common.core.uitls.GRpcUtil;
import com.bestcem.xm.common.core.uitls.IpUtil;
import com.bestcem.xm.common.core.uitls.JsonUtil;
import com.bestcem.xm.common.core.uitls.SignUtil;
import com.fasterxml.jackson.core.type.TypeReference;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.ConstraintViolation;
import java.util.Map;
import java.util.Set;

/**
 * 答题端完成答卷获取奖励
 *
 * @author jie.yao <jie.yao@idiaoyan.com>
 * @version v1.0
 * @date 2021/8/19 16:12
 */
@Slf4j
@RestController
@RequestMapping(value = "/award/v3", produces = MediaType.APPLICATION_JSON_VALUE)
public class RequestAwardController {

    @Resource
    private AwardDispatcher awardDispatcher;

    /**
     * 签名配置
     */
    @Resource
    protected SignConfig signConfig;

    private static final String DELIVER_ID = "deliver_id";

    /**
     * 答题端完成答卷获取奖励
     *
     * @param request              请求
     * @param getRequestAwardQuery 请求参数
     * @return 奖励信息
     * @author jie.yao <jie.yao@idiaoyan.com>
     * @date 2021/8/19 19:32
     */
    @PostMapping("/public")
    public XmResultJson<Map<String, Object>> getRequestAward(HttpServletRequest request,
                                                             @RequestBody GetRequestAwardQuery getRequestAwardQuery) {
        if (log.isInfoEnabled()) {
            log.info("请求奖励:{}", JSON.toJSONString(getRequestAwardQuery));
        }
        // 参数非空校验
        if (Validator.isNull(getRequestAwardQuery)) {
            return XmResultJson.fail(ReqErrorCodeConstants.PARAM_FORMAT, "requestBody is required");
        }
        if (Validator.isNull(getRequestAwardQuery.getDeliver())) {
            return XmResultJson.fail(ReqErrorCodeConstants.PARAM_FORMAT, "deliver is required");
        }
        if (Validator.isNull(getRequestAwardQuery.getRespondent())) {
            return XmResultJson.fail(ReqErrorCodeConstants.PARAM_FORMAT, "respondent is required");
        }
        if (Validator.isNull(getRequestAwardQuery.getDeliver().get(DELIVER_ID))) {
            return XmResultJson.fail(ReqErrorCodeConstants.PARAM_FORMAT, "该投放无奖励");
        }
        if (Validator.isNull(getRequestAwardQuery.getDeviceType())) {
            return XmResultJson.fail(ReqErrorCodeConstants.PARAM_FORMAT, "device_type is required");
        }
        // 验签
        boolean deliverSign = SignUtil.checkSign(getRequestAwardQuery.getDeliver(), signConfig.getDeliverKey());
        if (!deliverSign) {
            log.error("[award] deliver验签失败.deliver{},key:{}", JSON.toJSONString(getRequestAwardQuery.getDeliver()), signConfig.getDeliverKey());
            return XmResultJson.fail(ReqErrorCodeConstants.SIGN_ERROR, "invalid signature");
        }
        boolean respondentSign = SignUtil.checkSign(getRequestAwardQuery.getRespondent(), signConfig.getSurveyKey());
        if (!respondentSign) {
            log.error("[award] respondent验签失败.respondent{},key:{}", JSON.toJSONString(getRequestAwardQuery.getRespondent()), signConfig.getSurveyKey());
            return XmResultJson.fail(ReqErrorCodeConstants.SIGN_ERROR, "invalid signature");
        }
        // 请求端ip
        String remoteIp = IpUtil.getIpAddress(request);
        // 参数转换成service层所需参数
        GetRequestAwardParam param = getRequestAwardQuery.getRequestAwardParam(remoteIp);
        // 参数校验
        Set<ConstraintViolation<Object>> violations = GRpcUtil.validateParam(param);
        if (!CollectionUtils.isEmpty(violations)) {
            ConstraintViolation<Object> violation = violations.iterator().next();
            return XmResultJson.fail(ReqErrorCodeConstants.PARAM_FORMAT, violation.getMessage());
        }
        ServiceResult<String> serviceResult = awardDispatcher.requestAward(param);
        if (serviceResult.isSuccess()) {
            Map<String, Object> resultMap = JsonUtil.jsonToTransfer(serviceResult.getData(), new TypeReference<Map<String, Object>>() {
            });
            return XmResultJson.success(resultMap);
        } else {
            return XmResultJson.fail(1, serviceResult.getMsg());
        }
    }
}
